import * as fs from 'fs-extra';
import * as path from 'path';
import { glob } from 'glob';

export interface FileAnalysisResult {
  totalFiles: number;
  javaFiles: number;
  largeFiles: Array<{
    path: string;
    lines: number;
    reason: string;
  }>;
  testCoverage: {
    sourceFiles: number;
    testFiles: number;
    coverage: number;
  };
}

export class FileAnalyzer {
  async findJavaFiles(projectPath: string): Promise<string[]> {
    const pattern = path.join(projectPath, '**/*.java').replace(/\\/g, '/');
    const files = await glob(pattern, {
      ignore: [
        '**/target/**',
        '**/build/**',
        '**/.git/**',
        '**/node_modules/**'
      ]
    });
    return files;
  }

  async analyzeProject(projectPath: string): Promise<FileAnalysisResult> {
    const javaFiles = await this.findJavaFiles(projectPath);
    const largeFiles = [];
    
    for (const file of javaFiles) {
      const content = await fs.readFile(file, 'utf-8');
      const lines = content.split('\n').length;
      
      if (lines > 500) {
        largeFiles.push({
          path: file,
          lines,
          reason: `文件行数 ${lines} 超过500行限制`
        });
      }
    }

    // 分析测试覆盖率
    const sourceFiles = javaFiles.filter(f => !f.includes('/test/'));
    const testFiles = javaFiles.filter(f => f.includes('/test/'));
    const coverage = testFiles.length > 0 ? (testFiles.length / sourceFiles.length) * 100 : 0;

    return {
      totalFiles: javaFiles.length,
      javaFiles: javaFiles.length,
      largeFiles,
      testCoverage: {
        sourceFiles: sourceFiles.length,
        testFiles: testFiles.length,
        coverage: Math.round(coverage)
      }
    };
  }

  async getFileContent(filePath: string): Promise<string> {
    return await fs.readFile(filePath, 'utf-8');
  }

  async writeFileContent(filePath: string, content: string): Promise<void> {
    await fs.writeFile(filePath, content, 'utf-8');
  }

  async createBackup(filePath: string): Promise<string> {
    const backupPath = `${filePath}.backup.${Date.now()}`;
    await fs.copy(filePath, backupPath);
    return backupPath;
  }

  async listFilesInDirectory(dirPath: string, extension?: string): Promise<string[]> {
    const files = await fs.readdir(dirPath, { withFileTypes: true });
    return files
      .filter(file => file.isFile())
      .map(file => file.name)
      .filter(name => !extension || name.endsWith(extension));
  }

  async getFileStats(filePath: string): Promise<{
    size: number;
    lines: number;
    lastModified: Date;
  }> {
    const stats = await fs.stat(filePath);
    const content = await fs.readFile(filePath, 'utf-8');
    const lines = content.split('\n').length;

    return {
      size: stats.size,
      lines,
      lastModified: stats.mtime
    };
  }

  async findFilesByPattern(projectPath: string, pattern: string): Promise<string[]> {
    const fullPattern = path.join(projectPath, pattern).replace(/\\/g, '/');
    return await glob(fullPattern);
  }

  async isProjectStructureValid(projectPath: string): Promise<{
    isValid: boolean;
    issues: string[];
    suggestions: string[];
  }> {
    const issues: string[] = [];
    const suggestions: string[] = [];
    
    // 检查是否有pom.xml或build.gradle
    const hasPom = await fs.pathExists(path.join(projectPath, 'pom.xml'));
    const hasGradle = await fs.pathExists(path.join(projectPath, 'build.gradle'));
    
    if (!hasPom && !hasGradle) {
      issues.push('未找到构建文件 (pom.xml 或 build.gradle)');
      suggestions.push('这可能不是一个标准的Java项目');
    }

    // 检查标准目录结构
    const srcMainJava = path.join(projectPath, 'src', 'main', 'java');
    const srcTestJava = path.join(projectPath, 'src', 'test', 'java');
    
    if (!await fs.pathExists(srcMainJava)) {
      issues.push('未找到标准源码目录 src/main/java');
      suggestions.push('建议创建标准的Maven/Gradle目录结构');
    }

    if (!await fs.pathExists(srcTestJava)) {
      issues.push('未找到测试目录 src/test/java');
      suggestions.push('建议添加单元测试');
    }

    return {
      isValid: issues.length === 0,
      issues,
      suggestions
    };
  }
}